﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using E4D.AppFabric.Entities.Engine;
using System.Management.Automation;
using Microsoft.ApplicationServer.Caching.AdminApi;
using MDCAdminTool;

namespace UnitTests
{
    [TestClass]
    public class CacheClusterTests
    {
        private IList<Command> executedCommands = new List<Command>();
        private IDictionary<String, Collection<PSObject>> response = new Dictionary<String, Collection<PSObject>>();

        ISessionFactory getMockSessionFactory()
        {
            return new Mocks.MockSessionFactory(executedCommands, response);
        }

        //Fills response for Get-CacheHost request
        private void initTestCluster()
        {
            Collection<PSObject> cluster = new Collection<PSObject>();

            HostInfo hostInfo = new HostInfo("Host1", 111, "Service1", ServiceStatus.Up, new VersionInfo(1, 1, 1));
            PSObject hostInfoObj = new PSObject(hostInfo);

            cluster.Add(hostInfoObj);

            response.Add("Get-CacheHost", cluster);
        }

        private void initTestCache()
        {
            Collection<PSObject> cache = new Collection<PSObject>();

            //CacheInfo does not have a public constructor
            //CacheInfo cacheInfo = new CacheInfo();
            //PSObject cacheInfoObj = new PSObject(cacheInfo);

            //cache.Add(cacheInfoObj);

            response.Add("Get-Cache", cache);
        }

        

        [TestCleanup()]
        public void Cleanup()
        {
            executedCommands.Clear();
            response.Clear();
        }

        [TestMethod]
        public void TestCacheClusterStart()
        {
            //INIT
            SessionFactory.changeFactory(getMockSessionFactory());
            CacheCluster cluster = new CacheCluster();

            //ACT
            cluster.SetCacheCluster("Cluster1", "XML", "connection-string");
            cluster.Start();

            //ASSERT
            Assert.IsTrue(executedCommands.Count == 3);
            Assert.IsTrue(executedCommands[0].Name == "Use-CacheCluster");
            Assert.IsTrue(executedCommands[1].Name == "Start-CacheCluster");
            Assert.IsTrue(executedCommands[2].Name == "Get-CacheHost");

            Assert.IsNotNull(executedCommands[0].Parameters);
            Assert.IsTrue(executedCommands[0].Parameters.Count == 2);
            Assert.IsTrue(executedCommands[0].Parameters["Provider"].Equals("XML"));
            Assert.IsTrue(executedCommands[0].Parameters["ConnectionString"].Equals("connection-string"));

            Assert.IsNotNull(executedCommands[1].Parameters);
            Assert.IsTrue(executedCommands[1].Parameters.Count == 0);

            Assert.IsNotNull(executedCommands[2].Parameters);
            Assert.IsTrue(executedCommands[2].Parameters.Count == 0);

        }

        [TestMethod]
        public void TestCacheClusterStart2()
        {
            //INIT
            SessionFactory.changeFactory(getMockSessionFactory());
            CacheCluster cluster = new CacheCluster();
            initTestCluster();
            initTestCache();
            
            //ACT
            cluster.SetCacheCluster("Cluster1", "XML", "connection-string");
            cluster.Start();

            //ASSERT
            Assert.IsTrue(executedCommands.Count == 7);
            Assert.IsTrue(executedCommands[0].Name == "Use-CacheCluster");
            Assert.IsTrue(executedCommands[1].Name == "Start-CacheCluster");
            Assert.IsTrue(executedCommands[2].Name == "Get-CacheHost");
            Assert.IsTrue(executedCommands[3].Name == "Use-CacheCluster");
            Assert.IsTrue(executedCommands[4].Name == "Get-Cache");
            Assert.IsTrue(executedCommands[5].Name == "Use-CacheCluster");
            Assert.IsTrue(executedCommands[6].Name == "Get-CacheHostConfig");

            Assert.IsNotNull(executedCommands[0].Parameters);
            Assert.IsTrue(executedCommands[0].Parameters.Count == 2);
            Assert.IsTrue(executedCommands[0].Parameters["Provider"].Equals("XML"));
            Assert.IsTrue(executedCommands[0].Parameters["ConnectionString"].Equals("connection-string"));

            Assert.IsNotNull(executedCommands[1].Parameters);
            Assert.IsTrue(executedCommands[1].Parameters.Count == 0);

            Assert.IsNotNull(executedCommands[2].Parameters);
            Assert.IsTrue(executedCommands[2].Parameters.Count == 0);

            Assert.IsNotNull(executedCommands[3].Parameters);
            Assert.IsTrue(executedCommands[3].Parameters.Count == 2);
            Assert.IsTrue(executedCommands[3].Parameters["Provider"].Equals("XML"));
            Assert.IsTrue(executedCommands[3].Parameters["ConnectionString"].Equals("connection-string"));

            Assert.IsNotNull(executedCommands[4].Parameters);
            Assert.IsTrue(executedCommands[4].Parameters.Count == 0);

            Assert.IsNotNull(executedCommands[5].Parameters);
            Assert.IsTrue(executedCommands[5].Parameters.Count == 2);
            Assert.IsTrue(executedCommands[5].Parameters["Provider"].Equals("XML"));
            Assert.IsTrue(executedCommands[5].Parameters["ConnectionString"].Equals("connection-string"));

            Assert.IsNotNull(executedCommands[6].Parameters);
            Assert.IsTrue(executedCommands[6].Parameters.Count == 2);
            Assert.IsTrue(executedCommands[6].Parameters["HostName"].Equals("Host1"));
            Assert.IsTrue(executedCommands[6].Parameters["CachePort"].Equals(111));

            Assert.IsTrue(cluster.Hosts.Count == 1);
            Assert.IsTrue(cluster.Hosts[0].Name.Equals("Host1"));
            Assert.IsTrue(cluster.Hosts[0].CachePort == 111);
            Assert.IsTrue(cluster.Hosts[0].ServiceName.Equals("Service1"));
            Assert.IsTrue(cluster.Hosts[0].Status == ServiceStatus.Up);

            Assert.IsTrue(cluster.Groups.Count == 3);
            Assert.IsInstanceOfType(cluster.Groups[0], typeof(HostGroup));
            Assert.IsInstanceOfType(cluster.Groups[1], typeof(CacheGroup));
            Assert.IsInstanceOfType(cluster.Groups[2], typeof(CacheGroupHA));

            Assert.IsTrue(((HostGroup)cluster.Groups[0]).Hosts.Count == 1);
            Assert.IsTrue(((CacheGroup)cluster.Groups[1]).CacheNames.Count == 0);
            Assert.IsTrue(((CacheGroupHA)cluster.Groups[2]).CacheNames.Count == 0);
        }


        [TestMethod]
        public void TestUseCacheCluster()
        {
            //INIT
            SessionFactory.changeFactory(getMockSessionFactory());
            CacheCluster cluster = new CacheCluster();

            //ACT
            cluster.SetCacheCluster("Cluster1", "XML", "connection-string");
            cluster.UseCacheCluster();

            //ASSERT
            Assert.IsTrue(executedCommands.Count == 1);
            Assert.IsTrue(executedCommands[0].Name == "Use-CacheCluster");

            Assert.IsNotNull(executedCommands[0].Parameters);
            Assert.IsTrue(executedCommands[0].Parameters.Count == 2);
            Assert.IsTrue(executedCommands[0].Parameters["Provider"].Equals("XML"));
            Assert.IsTrue(executedCommands[0].Parameters["ConnectionString"].Equals("connection-string"));
        }

    }
}
